home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Source / GNU / cctools / as / hppa.c < prev    next >
C/C++ Source or Header  |  1994-07-28  |  46KB  |  1,830 lines

  1. /* hppa.c -- Assemble for the HP-PA
  2.    Copyright (C) 1989 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. /*
  22.    HP PA-RISC support was contributed by the Center for Software Science
  23.    at the University of Utah.
  24. */
  25.  
  26. /* HP-PA support for Mach-O ... USV */
  27.  
  28. #include <stdio.h>
  29. #include <ctype.h>
  30. #include <string.h>
  31. #include <mach-o/hppa/reloc.h>
  32. #define HPPA_RELOC_12BRANCH (127) /* only used internal in here */
  33.  
  34. #include "obstack.h"
  35. #include "hppa-opcode.h"
  36. #include "as.h"
  37. #include "frags.h"
  38. #include "flonum.h"
  39. #include "hash.h"
  40. #include "md.h"
  41. #include "symbols.h"
  42. #include "hppa-aux.h"
  43. #include "messages.h"
  44. #include "stuff/hppa.h"
  45.  
  46. /*
  47.  * These are the default cputype and cpusubtype for the hppa architecture.
  48.  */
  49. const cpu_type_t md_cputype = CPU_TYPE_HPPA;
  50. cpu_subtype_t md_cpusubtype = CPU_SUBTYPE_HPPA_ALL;
  51.  
  52. /* This is the byte sex for the hppa architecture */
  53. const enum byte_sex md_target_byte_sex = BIG_ENDIAN_BYTE_SEX;
  54.  
  55. /* These characters start a comment anywhere on the line */
  56. const char md_comment_chars[] = ";";
  57.  
  58. /* These characters only start a comment at the beginning of a line */
  59. const char md_line_comment_chars[] = "#";
  60.  
  61. /*
  62.  * These characters can be used to separate mantissa decimal digits from 
  63.  * exponent decimal digits in floating point numbers.
  64.  */
  65. const char md_EXP_CHARS[] = "eE";
  66.  
  67. /*
  68.  * The characters after a leading 0 that means this number is a floating point
  69.  * constant as in 0f123.456 or 0d1.234E-12 (see md_EXP_CHARS above).
  70.  */
  71. const char md_FLT_CHARS[] = "dDfF";
  72.  
  73. /*
  74.  * This is the machine dependent pseudo opcode table for this target machine.
  75.  */
  76. const pseudo_typeS md_pseudo_table[] =
  77. {
  78.     {0} /* end of table marker */
  79. };
  80.  
  81.  
  82. static int found_jbsr = 0;
  83. static char *toP;
  84.  
  85. const relax_typeS md_relax_table[] = { 0 };
  86.  
  87. /* handle of the OPCODE hash table */
  88. static struct hash_control *op_hash = NULL;
  89.  
  90. struct pa_it the_insn;   /* this structure is defined in pa-aux.h */
  91.  
  92. char *expr_end;
  93.  
  94. static void pa_ip(
  95.     char *str);
  96. static int parse_L_or_R(
  97.     char *str);
  98. static unsigned long parse_completer_with_cache_control_hint(
  99.     char    **s,       /* Note : the function changes '*s' */
  100.     int     option,    /* option = 0 for store instruction */
  101.                        /* option = 1 for load and clear instruction */
  102.     char    completer);/* 'c' or 'C' */
  103. static unsigned long parse_cache_control_hint(
  104.     char    **s,       /* Note : the function changes '*s' */
  105.     int     option);   /* option = 0 for store instruction */
  106.                        /* option = 1 for load and clear instruction */
  107.  
  108. /* This function is called once, at assembler startup time.  It should
  109.    set up all the tables, etc. that the MD part of the assembler will need.  */
  110. void
  111. md_begin(
  112. void)
  113. {
  114.     register char *retval = NULL;
  115.     int lose = 0;
  116.     register unsigned int i = 0;
  117.  
  118.     op_hash = hash_new();
  119.     if (op_hash == NULL)
  120.     as_fatal("Virtual memory exhausted");
  121.  
  122.     while (i < NUMOPCODES) {
  123.         const char *name = pa_opcodes[i].name;
  124.         retval = hash_insert(op_hash, (char *)name,
  125.                      (char *)&pa_opcodes[i]);
  126.         if(retval != NULL && *retval != '\0')  {
  127.             as_fatal("Internal error: can't hash `%s': %s\n",
  128.             pa_opcodes[i].name, retval);
  129.             lose = 1;
  130.         }
  131.         ++i;
  132.     }
  133.  
  134.     if (lose)
  135.         as_fatal ("Broken assembler.  No assembly attempted.");
  136. }
  137.  
  138. void
  139. md_end(
  140. void)
  141. {
  142.     return;
  143. }
  144.  
  145. void
  146. md_assemble(
  147. char *str)
  148. {
  149.  
  150.     assert(str);
  151.     pa_ip(str);
  152.     if (!found_jbsr)
  153.         toP = frag_more(4);
  154.     else
  155.         found_jbsr = 0;
  156.  
  157.     /* put out the opcode */
  158.     md_number_to_chars(toP, the_insn.opcode, 4);
  159.  
  160.     /* put out the symbol-dependent stuff */
  161.     if (the_insn.reloc != NO_RELOC) {
  162.         fix_new(frag_now,              /* which frag */
  163.             (toP - frag_now->fr_literal), /* where */
  164.             4,                  /* size */
  165.             the_insn.exp.X_add_symbol,
  166.             the_insn.exp.X_subtract_symbol,
  167.             the_insn.exp.X_add_number,      /* offset */
  168.             the_insn.pcrel,
  169.             the_insn.pcrel_reloc,
  170.             the_insn.reloc);
  171.     }
  172. }
  173.  
  174. static
  175. void
  176. pa_ip(
  177. char *str)
  178. {
  179.     char *s;
  180.     const char *args;
  181.     char c;
  182.     unsigned long i;
  183.     struct pa_opcode *insn;
  184.     char *argsStart;
  185.     unsigned long   opcode;
  186.     int match = FALSE;
  187.     int comma = 0;
  188.  
  189.     int reg,reg1,reg2,s2,s3;
  190.     unsigned int im21,im14,im11,im5;
  191.     int m,a,u,f;
  192.     int cmpltr,nullif, flag;
  193.     int sfu, cond;
  194.     char *name;
  195.     char *save_s;
  196.  
  197. #ifdef PA_DEBUG
  198.     fprintf(stderr,"STATEMENT: \"%s\"\n",str);
  199. #endif
  200.     for (s = str; isupper(*s) || islower(*s) || (*s >= '0' && *s <= '3'); ++s)
  201.         ;
  202.     switch (*s) {
  203.  
  204.     case '\0':
  205.         break;
  206.  
  207.     case ',':
  208.         comma = 1;
  209.  
  210.     /*FALLTHROUGH*/
  211.  
  212.     case ' ':
  213.         *s++ = '\0';
  214.         break;
  215.  
  216.     default:
  217.         as_bad("Unknown opcode: `%s'", str);
  218.         exit(1);
  219.     }
  220.  
  221.     save_s = str;
  222.  
  223.     while ( *save_s ) {
  224.         if ( isupper(*save_s) )
  225.             *save_s = tolower(*save_s);
  226.         save_s++;
  227.     }
  228.  
  229.     if ((insn = (struct pa_opcode *) hash_find(op_hash, str)) == NULL) {
  230.         as_bad("Unknown opcode: `%s'", str);
  231.         return;
  232.     }
  233.     if (comma) {
  234.         *--s = ',';
  235.     }
  236.     argsStart = s;
  237.     for (;;) {
  238.         opcode = insn->match;
  239.         memset(&the_insn, '\0', sizeof(the_insn));
  240.         the_insn.reloc = NO_RELOC;    /* USV */
  241.  
  242. /*
  243. * Build the opcode, checking as we go to make
  244. * sure that the operands match
  245. */
  246.         for (args = insn->args; ; ++args) {
  247.  
  248.             switch (*args) {
  249.  
  250.             case '\0':  /* end of args */
  251.                   if (*s == '\0') {
  252.                     match = TRUE;
  253.                   }
  254.                   break;
  255.  
  256.             case '(':   /* these must match exactly */
  257.             case ')':
  258.             case ',':
  259.             case ' ':
  260.                   if (*s++ == *args)
  261.                     continue;
  262.                   break;
  263.  
  264.             case 'b':   /* 5 bit register field at 10 */
  265.                   reg = pa_parse_number(&s);
  266.                   if ( reg < 32 && reg >= 0 ) {
  267.                     opcode |= reg << 21;
  268.                     continue;
  269.                   }
  270.                   break;
  271.             case 'x':   /* 5 bit register field at 15 */
  272.                   reg = pa_parse_number(&s);
  273.                   if ( reg < 32 && reg >= 0 ) {
  274.                     opcode |= reg << 16;
  275.                     continue;
  276.                   }
  277.                   break;
  278.             case 't':   /* 5 bit register field at 31 */
  279.                   reg = pa_parse_number(&s);
  280.                   if ( reg < 32 && reg >= 0 ) {
  281.                     opcode |= reg;
  282.                     continue;
  283.                   }
  284.                   break;
  285.             case 'T':   /* 5 bit field length at 31 (encoded as 32-T) */
  286.   /*
  287. reg = pa_parse_number(&s);
  288.    */
  289.                 getAbsoluteExpression(s);
  290.                   if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  291.                     reg = the_insn.exp.X_add_number;
  292.                     if ( reg <= 32 && reg > 0 ) {
  293.                           opcode |= 32 - reg;
  294.                           s = expr_end;
  295.                           continue;
  296.                     }
  297.                   }
  298.                   break;
  299.             case '5':   /* 5 bit immediate at 15 */
  300.                 getAbsoluteExpression(s);
  301. /** PJH: The following 2 calls to as_bad() might eventually **/
  302. /**      want to end up as as_warn().  **/
  303.                 if (   the_insn.exp.X_add_number > 15 ) {
  304.                     as_bad("5 bit immediate: %ld > 15. Set to 15",
  305.                         the_insn.exp.X_add_number);
  306.                     the_insn.exp.X_add_number = 15;
  307.                 }
  308.                 else if ( the_insn.exp.X_add_number < -16 ) {
  309.                         as_bad("5 bit immediate: %ld < -16. Set to -16",
  310.                             the_insn.exp.X_add_number);
  311.                         the_insn.exp.X_add_number = -16;
  312.                     }
  313.  
  314.                 im5 = low_sign_unext(evaluateAbsolute(
  315.                              the_insn.exp,0),5);
  316.                 opcode |= ( im5 << 16 );
  317.                 s = expr_end;
  318.                 continue;
  319.  
  320.             case 's':   /* 2 bit space identifier at 17 */
  321.                 s2 = pa_parse_number(&s);
  322.                 if ( s2 < 4 && s2 >= 0 ) {
  323.                     opcode |= s2 << 14;
  324.                     continue;
  325.                 }
  326.                 break;
  327.             case 'S':   /* 3 bit space identifier at 18 */
  328.                 s3 = pa_parse_number(&s);
  329.                 if ( s3 < 8 && s3 >= 0 ) {
  330.                     s3 = dis_assemble_3(s3);
  331.                     opcode |= s3 << 13;
  332.                     continue;
  333.                 }
  334.                 break;
  335.             case 'c':   /* indexed load completer. */
  336.                 i = m = u = 0;
  337.                 while ( *s == ',' && i < 2 ) {
  338.                     s++;
  339.                     if ( strncasecmp(s,"sm",2) == 0 ) {
  340.                         m = u = 1;
  341.                         s++;
  342.                         i++;
  343.                     }
  344.                     else if ( strncasecmp(s,"m",1) == 0 )
  345.                               m = 1;
  346.                         else if ( strncasecmp(s,"s",1) == 0 )
  347.                                   u = 1;
  348.                             else
  349.                                   as_bad("Unrecognized Indexed Load"
  350.                                     "Completer...assuming 0");
  351.                     s++;
  352.                     i++;
  353.                   }
  354.                   if ( i > 2 )
  355.                     as_bad("Illegal Indexed Load Completer Syntax..."
  356.                         "extras ignored");
  357.                   while ( *s == ' ' || *s == '\t' )
  358.                     s++;
  359.   
  360.                   opcode |= m << 5;
  361.                   opcode |= u << 13;
  362.                   continue;
  363.             case 'C':   /* short load and store completer */
  364.                 m = a = 0;
  365.                 if ( *s == ',' ) {
  366.                     s++;
  367.                     if ( strncasecmp(s,"ma",2) == 0 ) {
  368.                         a = 0;
  369.                         m = 1;
  370.                     }
  371.                     else if ( strncasecmp(s,"mb",2) == 0 ) {
  372.                             m = a = 1;
  373.                         }
  374.                         else
  375.                             as_bad("Unrecognized Indexed Load Completer"
  376.                                 "...assuming 0");
  377.                     s += 2;
  378.                 }
  379.                 while ( *s == ' ' || *s == '\t' )
  380.                     s++;
  381.                 opcode |= m << 5;
  382.                 opcode |= a << 13;
  383.                 continue;
  384.  
  385.             /* bug #41317 .... umeshv@NeXT.com
  386.              * Fri Jul 22 09:43:46 PDT 1994
  387.              *
  388.              * Modified to parse 'cache control hints'
  389.              *
  390.              * These parse ",cc" and encode "cc" in 2 bits at 20,
  391.              * where "cc" encoding is as given in Tables 5-8, 5-9.
  392.              * Refer to 'PA-RISC 1.1 Architecture and Instruction Set
  393.              * Reference Manual, Second Edition' for the tables.
  394.              */
  395.             case 'Y':   /* Store Bytes Short completer */
  396.                         /* with cache control hints    */
  397.             {
  398.                 unsigned long result = (unsigned long)0UL;
  399.                 
  400.                 i = m = a = 0;
  401.                 while ( *s == ',' && i < 3 ) {
  402.                     s++;
  403.                     if ( strncasecmp(s,"m",1) == 0 )
  404.                         m = 1;
  405.                     else if ( strncasecmp(s,"b",1) == 0 &&
  406.                               (strncasecmp((s+1),"c",1) != 0) )
  407.                             a = 0;
  408.                         else if ( strncasecmp(s,"e",1) == 0 )
  409.                                 a = 1;
  410.                             else if ( strncmp(s,",",1) == 0 ) /* no completer */
  411.                                 result |= parse_cache_control_hint(&s, 0);
  412.                             else if ( (strncasecmp(s,"c",1) == 0) ||
  413.                                       (strncasecmp(s,"b",1) == 0) ) {/* just 1 completer */
  414.                                 s--;
  415.                                 result |= parse_cache_control_hint(&s, 0);
  416.                             }
  417.                             else
  418.                                 as_bad("Unrecognized Store Bytes Short"
  419.                                     "Completer with cache control hints"
  420.                                     " ...assuming 0");
  421.                     if (result == (unsigned long)0UL)
  422.                         s++;
  423.                     i++;
  424.                 }
  425. /**        if ( i >= 2 ) **/
  426.                 if ( i > 3 )
  427.                     as_bad("Illegal Store Bytes Short Completer "
  428.                         "with cache control hints ...  extras ignored");
  429.                 while ( *s == ' ' || *s == '\t' ) /* skip to next operand */
  430.                     s++;
  431.                 opcode |= result;
  432.                 opcode |= m << 5;
  433.                 opcode |= a << 13;
  434.                 continue;
  435.             }
  436.             case '<':   /* non-negated compare/subtract conditions. */
  437.                 cmpltr = pa_parse_nonneg_cmpsub_cmpltr(&s);
  438.                 if ( cmpltr < 0 ) {
  439.                     as_bad("Unrecognized Compare/Subtract Condition: %c",*s);
  440.                     cmpltr = 0;
  441.                 }
  442.                 opcode |= cmpltr << 13;
  443.                 continue;
  444.             case '?':   /* negated or non-negated cmp/sub conditions. */
  445.                     /* used only by ``comb'' and ``comib'' pseudo-ops */
  446.                 save_s = s;
  447.                 cmpltr = pa_parse_nonneg_cmpsub_cmpltr(&s);
  448.                 if ( cmpltr < 0 ) {
  449.                     s = save_s;
  450.                     cmpltr = pa_parse_neg_cmpsub_cmpltr(&s);
  451.                     if ( cmpltr < 0 ) {
  452.                         as_bad("Unrecognized Compare/Subtract Condition: %c"
  453.                             ,*s);
  454.                         cmpltr = 0;
  455.                     }
  456.                     else {
  457.                         opcode |= 1 << 27; /* required opcode change to make
  458.                                             COMIBT into a COMIBF or a
  459.                                             COMBT into a COMBF or a
  460.                                             ADDBT into a ADDBF or a
  461.                                             ADDIBT into a ADDIBF */
  462.                     }
  463.                 }
  464.                 opcode |= cmpltr << 13;
  465.                 continue;
  466.             case '!':   /* negated or non-negated add conditions. */
  467.                 /* used only by ``addb'' and ``addib'' pseudo-ops */
  468.                 save_s = s;
  469.                 cmpltr = pa_parse_nonneg_add_cmpltr(&s);
  470.                 if ( cmpltr < 0 ) {
  471.                     s = save_s;
  472.                     cmpltr = pa_parse_neg_add_cmpltr(&s);
  473.                     if ( cmpltr < 0 ) {
  474.                         as_bad("Unrecognized Compare/Subtract Condition: %c",
  475.                             *s);
  476.                         cmpltr = 0;
  477.                     }
  478.                     else {
  479.                         opcode |= 1 << 27; /* required opcode change to make
  480.                                             COMIBT into a COMIBF or a
  481.                                             COMBT into a COMBF or a
  482.                                             ADDBT into a ADDBF or a
  483.                                             ADDIBT into a ADDIBF */
  484.                     }
  485.                 }
  486.                 opcode |= cmpltr << 13;
  487.                 continue;
  488.             case '-':   /* compare/subtract conditions */
  489.                 f = cmpltr = 0;
  490.                 save_s = s;
  491.                 if ( *s == ',' ) {
  492.                     cmpltr = pa_parse_nonneg_cmpsub_cmpltr(&s);
  493.                     if ( cmpltr < 0 ) {
  494.                         f = 1;
  495.                         s = save_s;
  496.                         cmpltr = pa_parse_neg_cmpsub_cmpltr(&s);
  497.                         if ( cmpltr < 0 ) {
  498.                             as_bad("Unrecognized Compare/Subtract Condition");
  499.                         }
  500.                     }
  501.                 }
  502.                 opcode |= cmpltr << 13;
  503.                 opcode |= f << 12;
  504.                 continue;
  505.             case '+':   /* non-negated add conditions */
  506.                 flag = nullif = cmpltr = 0;
  507.                 if ( *s == ',' ) {
  508.                     s++;
  509.                     name = s;
  510.                     while ( *s != ',' && *s != ' ' && *s != '\t' )
  511.                         s += 1;
  512.                     c = *s;
  513.                     *s = 0x00;
  514.                     if ( strcmp(name,"=") == 0 ) {
  515.                         cmpltr = 1;
  516.                         }
  517.                         else if ( strcmp(name,"<") == 0 ) {
  518.                         cmpltr = 2;
  519.                         }
  520.                         else if ( strcmp(name,"<=") == 0 ) {
  521.                         cmpltr = 3;
  522.                         }
  523.                         else if ( strcasecmp(name,"nuv") == 0 ) {
  524.                         cmpltr = 4;
  525.                         }
  526.                         else if ( strcasecmp(name,"znv") == 0 ) {
  527.                         cmpltr = 5;
  528.                         }
  529.                         else if ( strcasecmp(name,"sv") == 0 ) {
  530.                         cmpltr = 6;
  531.                         }
  532.                         else if ( strcasecmp(name,"od") == 0 ) {
  533.                         cmpltr = 7;
  534.                         }
  535.                         else if ( strcasecmp(name,"n") == 0 ) {
  536.                         nullif = 1;
  537.                         }
  538.                         else if ( strcasecmp(name,"tr") == 0 ) {
  539.                         cmpltr = 0;
  540.                         flag   = 1;
  541.                         }
  542.                         else if ( strcasecmp(name,"<>") == 0 ) {
  543.                         flag = cmpltr = 1;
  544.                         }
  545.                         else if ( strcasecmp(name,">=") == 0 ) {
  546.                         cmpltr = 2;
  547.                         flag   = 1;
  548.                         }
  549.                         else if ( strcasecmp(name,">") == 0 ) {
  550.                         cmpltr = 3;
  551.                         flag   = 1;
  552.                         }
  553.                         else if ( strcasecmp(name,"uv") == 0 ) {
  554.                         cmpltr = 4;
  555.                         flag   = 1;
  556.                         }
  557.                         else if ( strcasecmp(name,"vnz") == 0 ) {
  558.                         cmpltr = 5;
  559.                         flag   = 1;
  560.                         }
  561.                         else if ( strcasecmp(name,"nsv") == 0 ) {
  562.                         cmpltr = 6;
  563.                         flag   = 1;
  564.                         }
  565.                         else if ( strcasecmp(name,"ev") == 0 ) {
  566.                         cmpltr = 7;
  567.                         flag   = 1;
  568.                         }
  569.                         else
  570.                         as_bad("Unrecognized Add Condition: %s",name);
  571.                     *s = c;
  572.                 }
  573.                 nullif = pa_parse_nullif(&s);
  574.                 opcode |= nullif << 1;
  575.                 opcode |= cmpltr << 13;
  576.                 opcode |= flag << 12;
  577.                 continue;        
  578.             case '&':   /* logical instruction conditions */
  579.                 f = cmpltr = 0;
  580.                 if ( *s == ',' ) {
  581.                     s++;
  582.                     name = s;
  583.                     while ( *s != ',' && *s != ' ' && *s != '\t' )
  584.                         s += 1;
  585.                     c = *s;
  586.                     *s = 0x00;
  587.                     if ( strcmp(name,"=") == 0 ) {
  588.                         cmpltr = 1;
  589.                         }
  590.                         else if ( strcmp(name,"<") == 0 ) {
  591.                         cmpltr = 2;
  592.                         }
  593.                         else if ( strcmp(name,"<=") == 0 ) {
  594.                         cmpltr = 3;
  595.                         }
  596.                         else if ( strcasecmp(name,"od") == 0 ) {
  597.                         cmpltr = 7;
  598.                         }
  599.                         else if ( strcasecmp(name,"tr") == 0 ) {
  600.                         cmpltr = 0;
  601.                         f = 1;
  602.                         }
  603.                         else if ( strcmp(name,"<>") == 0 ) {
  604.                         f = cmpltr = 1;
  605.                         }
  606.                         else if ( strcmp(name,">=") == 0 ) {
  607.                         cmpltr = 2;
  608.                         f = 1;
  609.                         }
  610.                         else if ( strcmp(name,">") == 0 ) {
  611.                         cmpltr = 3;
  612.                         f = 1;
  613.                         }
  614.                         else if ( strcasecmp(name,"ev") == 0 ) {
  615.                         cmpltr = 7;
  616.                         f = 1;
  617.                         }
  618.                         else
  619.                         as_bad("Unrecognized Logical Instruction Condition:"
  620.                             " %s",name);
  621.                     *s = c;
  622.                 }
  623.                 opcode |= cmpltr << 13;
  624.                 opcode |= f << 12;        
  625.                 continue;
  626.             case 'U':   /* unit instruction conditions */
  627.                 cmpltr = 0;
  628.                 f = 0;
  629.                 if ( *s == ',' ) {
  630.                     s++;
  631.                     if ( strncasecmp(s,"sbz",3) == 0 ) {
  632.                         cmpltr = 2;
  633.                         s += 3;
  634.                         }
  635.                         else if ( strncasecmp(s,"shz",3) == 0 ) {
  636.                         cmpltr = 3;
  637.                         s += 3;
  638.                         }
  639.                         else if ( strncasecmp(s,"sdc",3) == 0 ) {
  640.                         cmpltr = 4;
  641.                         s += 3;
  642.                         }
  643.                         else if ( strncasecmp(s,"sbc",3) == 0 ) {
  644.                         cmpltr = 6;
  645.                         s += 3;
  646.                         }
  647.                         else if ( strncasecmp(s,"shc",3) == 0 ) {
  648.                         cmpltr = 7;
  649.                         s += 3;
  650.                         }
  651.                         else if ( strncasecmp(s,"tr",2) == 0 ) {
  652.                         cmpltr = 0;
  653.                         f = 1;
  654.                         s += 2;
  655.                         }
  656.                         else if ( strncasecmp(s,"nbz",3) == 0 ) {
  657.                         cmpltr = 2;
  658.                         f = 1;
  659.                         s += 3;
  660.                         }
  661.                         else if ( strncasecmp(s,"nhz",3) == 0 ) {
  662.                         cmpltr = 3;
  663.                         f = 1;
  664.                         s += 3;
  665.                         }
  666.                         else if ( strncasecmp(s,"ndc",3) == 0 ) {
  667.                         cmpltr = 4;
  668.                         f = 1;
  669.                         s += 3;
  670.                         }
  671.                         else if ( strncasecmp(s,"nbc",3) == 0 ) {
  672.                         cmpltr = 6;
  673.                         f = 1;
  674.                         s += 3;
  675.                         }
  676.                         else if ( strncasecmp(s,"nhc",3) == 0 ) {
  677.                         cmpltr = 7;
  678.                         f = 1;
  679.                         s += 3;
  680.                         }
  681.                         else
  682.                         as_bad("Unrecognized Logical Instruction Condition:"
  683.                             " %c",*s);
  684.                 }
  685.                 opcode |= cmpltr << 13;
  686.                 opcode |= f << 12;        
  687.                 continue;
  688.             case '>':   /* shift/extract/deposit conditions. */
  689.                 cmpltr = 0;
  690.                 if ( *s == ',' ) {
  691.                     s++;
  692.                     name = s;
  693.                     while ( *s != ',' && *s != ' ' && *s != '\t' )
  694.                         s += 1;
  695.                     c = *s;
  696.                     *s = 0x00;
  697.                     if ( strcmp(name,"=") == 0 ) {
  698.                         cmpltr = 1;
  699.                         }
  700.                         else if ( strcmp(name,"<") == 0 ) {
  701.                         cmpltr = 2;
  702.                         }
  703.                         else if ( strcasecmp(name,"od") == 0 ) {
  704.                         cmpltr = 3;
  705.                         }
  706.                         else if ( strcasecmp(name,"tr") == 0 ) {
  707.                         cmpltr = 4;
  708.                         }
  709.                         else if ( strcmp(name,"<>") == 0 ) {
  710.                         cmpltr = 5;
  711.                         }
  712.                         else if ( strcmp(name,">=") == 0 ) {
  713.                         cmpltr = 6;
  714.                         }
  715.                         else if ( strcasecmp(name,"ev") == 0 ) {
  716.                         cmpltr = 7;
  717.                         }
  718.                         else
  719.                         as_bad("Unrecognized Shift/Extract/Deposit"
  720.                             "Condition: %s",name);
  721.                     *s = c;
  722.                 }
  723.                 opcode |= cmpltr << 13;
  724.                 continue;
  725.             case '~':   /* bvb,bb conditions */
  726.                 cmpltr = 0;
  727.                 if ( *s == ',' ) {
  728.                     s++;
  729.                     if ( strncmp(s,"<",1) == 0 ) {
  730.                         cmpltr = 2;
  731.                         s++;
  732.                         }
  733.                         else if ( strncmp(s,">=",2) == 0 ) {
  734.                         cmpltr = 6;
  735.                         s += 2;
  736.                         }
  737.                         else
  738.                         as_bad("Unrecognized Bit Branch Condition: %c",*s);
  739.                 }
  740.                 opcode |= cmpltr << 13;
  741.                 continue;
  742.             case 'V':   /* 5  bit immediate at 31 */
  743.                 getExpression(s);
  744.                 im5 = low_sign_unext(evaluateAbsolute(
  745.                              the_insn.exp,0),5);
  746.                 opcode |= im5;
  747.                 s = expr_end;
  748.                 continue;
  749.             case 'r':   /* 5  bit immediate at 31 */
  750.                         /* (unsigned value for the break instruction) */
  751.                 getExpression(s);
  752.                 im5 = evaluateAbsolute(the_insn.exp,0);
  753.                 if ( im5 > 31 ) {
  754.                     as_bad("Operand out of range. Was: %d. Should be"
  755.                         "[0..31]. Assuming %d.\n",im5,im5&0x1f);
  756.                     im5 = im5 & 0x1f;
  757.                 }
  758.                 opcode |= im5;
  759.                 s = expr_end;
  760.                 continue;
  761.             case 'R':   /* 5  bit immediate at 15 */
  762. /* (unsigned value for the ssm and rsm instruction) */
  763.                 getExpression(s);
  764.                 im5 = evaluateAbsolute(the_insn.exp,0);
  765.                 if ( im5 > 31 ) {
  766.                     as_bad("Operand out of range. Was: %d. Should be"
  767.                         "[0..31]. Assuming %d.\n",im5,im5&0x1f);
  768.                     im5 = im5 & 0x1f;
  769.                 }
  770.                 opcode |= im5 << 16;
  771.                 s = expr_end;
  772.                 continue;
  773.             case 'i':   /* 11 bit immediate at 31 */
  774.                 getExpression(s);
  775.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  776.                     im11 = low_sign_unext(evaluateAbsolute(
  777.                             the_insn.exp,0),11);
  778.                     opcode |= im11;
  779.                 }
  780.                 else {
  781.                     the_insn.code = 'i';
  782.                 }
  783.                 s = expr_end;
  784.                 continue;
  785.             case 'j':   /* 14 bit immediate at 31 --- LO14 */
  786.             {
  787.                 int field_selector = parse_L_or_R(s);
  788.                 switch (field_selector) {
  789.                 case 2:    /* found the field selector R`*/
  790.                 case 1:    /* found the field selector L`*/
  791.                     s += 2;  /* eat up L` or R` */
  792.                 case 0: /* not found */
  793.                     getExpression(s);
  794.                     break;
  795.                 default:
  796.                     as_bad("Bad field selector. Was: %.2s. Should be either L` or R`\n",s);
  797.                     break;
  798.                 }
  799.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  800.                     im14 = low_sign_unext(
  801. evaluateAbsolute(the_insn.exp,field_selector), 14);
  802.  
  803. /* I donot think the mask is necessary here  low_sign_unext() takes */
  804. /* care of putting only 14 bits in im14 ! ...       090993 ... USV  */
  805. /*                    if (field_selector)
  806.                         opcode |= (im14 & 0x7ff);
  807.                     else
  808. */
  809.                     opcode |= im14;
  810.                 }
  811.                 else {
  812.                     the_insn.reloc = HPPA_RELOC_LO14;
  813.                     the_insn.code = 'j';
  814.                 }
  815.                 s = expr_end;
  816.                 continue;
  817.             }  
  818.             case 'z':    /* 17 bit branch displacement (non-pc-relative) */
  819.                 /* for be, ble --- BR17*/
  820.                 /* bl, ble  in absence of L` or R` can have */
  821.                 /* a 17 bit immmidiate number */
  822.             {
  823.                 unsigned long w, w1, w2;
  824.                 int field_selector = parse_L_or_R(s);
  825.                 switch (field_selector) {
  826.                 case 2:    /* found the field selector R`*/
  827.                 case 1:    /* found the field selector L`*/
  828.                     s += 2;  /* eat up L` or R` */
  829.                 case 0: /* not found */
  830.                     getExpression(s);
  831.                     break;
  832.                 default:
  833.                     as_bad("Bad field selector. Was: %.2s." "Should be either L` or R`\n",s);
  834.                     break;
  835.                 }
  836.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  837.                     im14 = sign_unext(
  838.                         evaluateAbsolute(the_insn.exp,field_selector),
  839.                         17);
  840.                     dis_assemble_17(im14>>2,&w1,&w2,&w);
  841.                     opcode |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
  842.                 }
  843.                 else {
  844.                     the_insn.reloc = HPPA_RELOC_BR17;
  845.                     the_insn.code = 'z';
  846.                 }
  847.                 s = expr_end;
  848.                 continue;
  849.             }
  850.             case 'k':   /* 21 bit immediate at 31 --- HI21 */
  851.             {
  852.                 int field_selector = parse_L_or_R(s);
  853.                 switch (field_selector) {
  854.                 case 2:    /* found the field selector R`*/
  855.                 case 1:    /* found the field selector L`*/
  856.                     s += 2;  /* eat up L` or R` */
  857.                 case 0: /* not found */
  858.                     getExpression(s);
  859.                     break;
  860.                 default:
  861.                     as_bad("Bad field selector. Was: %.2s." "Should be either L` or R`\n",s);
  862.                     break;
  863.                 }
  864.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  865.                     im21 = dis_assemble_21(
  866. (evaluateAbsolute(the_insn.exp,field_selector) >> 11));
  867.                     opcode |=  im21 ;
  868.                 }
  869.                 else {
  870.                     the_insn.reloc = HPPA_RELOC_HI21;
  871.                     the_insn.code = 'k';
  872.                 }
  873.                 s = expr_end;
  874.                 continue;
  875.               }
  876.             case 'n':   /* nullification for branch instructions */
  877.                 nullif = pa_parse_nullif(&s);
  878.                 opcode |= nullif << 1;
  879.                 continue;        
  880.             case 'w':   /* 12 bit branch displacement */
  881.                 getExpression(s);
  882.                 the_insn.pcrel_reloc = 0;
  883.                 the_insn.pcrel = 1;
  884.                 if ( the_insn.exp.X_add_symbol ) {
  885.                     if ( strcmp(
  886. the_insn.exp.X_add_symbol->sy_nlist.n_un.n_name,"L0\001") == 0 ) {
  887.                         unsigned long w1,w,result;
  888.                     result = sign_unext( (the_insn.exp.X_add_number
  889.                             - 8) >> 2,
  890.                             12);
  891.                     dis_assemble_12(result,&w1,&w);
  892.                     opcode |= ( ( w1 << 2 ) | w );
  893.                     }
  894.                     else {
  895. /* this has to be wrong -- dont know what is right! */
  896. /*  the_insn.reloc = R_PCREL_CALL; */
  897.                         the_insn.reloc = HPPA_RELOC_12BRANCH;
  898.                         the_insn.code = 'w';
  899.                     }
  900.                 }
  901.                 else {
  902.                     unsigned long w1,w,result;
  903.                     result = sign_unext( the_insn.exp.X_add_number >> 
  904.                     2,12);
  905.                     dis_assemble_12(result,&w1,&w);
  906.                     opcode |= ( ( w1 << 2 ) | w );
  907.                 }
  908.                 s = expr_end;
  909.                 continue;
  910.             case 'W':   /* 17 bit branch displacement --- BL17 */
  911.                 getExpression(s);
  912.                 /*
  913.                  * The NeXT linker has the ability to scatter
  914.                  * blocks of sections between labels.  This
  915.                  * requires that brances to labels that survive
  916.                  * to the link phase must be able to be
  917.                  * relocated.
  918.                  */
  919.                 if(the_insn.exp.X_add_symbol != NULL &&
  920.                    (the_insn.exp.X_add_symbol->sy_name[0] != 'L'
  921.                     || flagseen['L']))
  922.                     the_insn.pcrel_reloc = 1;
  923.                 else
  924.                     the_insn.pcrel_reloc = 0;
  925.                 the_insn.pcrel = 1;
  926.                       if ( the_insn.exp.X_add_symbol ) {
  927.                     if ( strcmp(the_insn.exp.X_add_symbol->sy_nlist.n_un.n_name,"L0\001") == 0 ) {
  928.                         unsigned long w2,w1,w,result;
  929.  
  930.                         result = sign_unext( 
  931.                             (the_insn.exp.X_add_number - 8) >> 2,17);
  932.                         dis_assemble_17(result,&w1,&w2,&w);
  933.                         opcode |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
  934.                     }
  935.                     else {
  936.                          if ( (the_insn.reloc == HPPA_RELOC_JBSR) &&
  937.                                 (the_insn.exp.X_add_symbol->sy_name[0] != 'L') )
  938.                             as_fatal("Stub label used in a JBSR must be "
  939.                                 "non-relocatable");
  940.                         the_insn.reloc = HPPA_RELOC_BL17;
  941.                         the_insn.code = 'W';
  942.                     }
  943.                 }
  944.                 else {
  945.                     unsigned long w2,w1,w,result;
  946.  
  947.                     result = sign_unext( the_insn.exp.X_add_number >> 2,17);
  948.                     dis_assemble_17(result,&w1,&w2,&w);
  949.                     opcode |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
  950.                 }
  951.                 s = expr_end;
  952.                 continue;
  953.             case '@':   /* 17 bit branch displacement --- JBSR */
  954.                 getExpression(s);
  955.  
  956. /*
  957.  * assumption here is this will only be used in case of jbsr
  958.  * in which case the format is 
  959.  *        jbsr,n symbol,register,label
  960.  * and a relocation entry for symbol needs to be created
  961.  */
  962.  
  963.                 the_insn.pcrel = 0;
  964.                 the_insn.pcrel_reloc = 1;
  965.                 the_insn.reloc = HPPA_RELOC_JBSR;
  966.                 the_insn.code = '@';
  967.                 s = expr_end;
  968.  /*
  969.   * The code to hook a frag in the chain should be here.
  970.   * Then set a flag saying that the next 'W' should not create a relocation
  971.   * entry. The way 'jbsr' is expected to work is the label will always be
  972.   * local!
  973.   * This flag should be reset in 'W'.
  974.   */
  975.                 found_jbsr = 1;
  976.                 toP = frag_more(4);
  977.                 fix_new(frag_now,
  978.                     (toP - frag_now->fr_literal),
  979.                     4,
  980.                     the_insn.exp.X_add_symbol,
  981.                     the_insn.exp.X_subtract_symbol,
  982.                     the_insn.exp.X_add_number,
  983.                     the_insn.pcrel,
  984.                     the_insn.pcrel_reloc,
  985.                     the_insn.reloc);
  986.  
  987.                 continue;
  988.             case 'B':   /* either "s,b" or "b" where b & s are defined above */
  989.                 reg1 = pa_parse_number(&s);
  990.                 if ( *s == ',' ) {
  991.                     s++;
  992.                     reg2 = pa_parse_number(&s);
  993.                 }
  994.                 else {
  995.                     reg2 = reg1;
  996.                     reg1 = 0;
  997.                 }
  998.                 if ( reg1 < 4 && reg1 >= 0 ) {
  999.                     opcode |= reg1 << 14;
  1000.                     opcode |= reg2 << 21;
  1001.                     continue;
  1002.                 }
  1003.                 break;
  1004.             case 'p':   /* 5 bit shift count at 26 (to support SHD instr.) */
  1005.                         /* value is encoded in instr. as 31-p where p is   */
  1006.                         /* the value scanned here */
  1007.                 getExpression(s);
  1008.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  1009.                     opcode |= ( ( (31 - the_insn.exp.X_add_number) & 0x1f ) << 5 );
  1010.                 }
  1011.                 s = expr_end;
  1012.                 continue;
  1013.             case 'P':   /* 5-bit bit position at 26 */
  1014.                 getExpression(s);
  1015.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  1016.                     opcode |= ( the_insn.exp.X_add_number & 0x1f ) << 5;
  1017.                 }
  1018.                 s = expr_end;
  1019.                 continue;
  1020.             case 'Q':   /* 5  bit immediate at 10 */
  1021.                         /* (unsigned bit position value for the bb instruction) */
  1022.                 getExpression(s);
  1023.                 im5 = evaluateAbsolute(the_insn.exp,0);
  1024.                 if ( im5 > 31 ) {
  1025.                     as_bad("Operand out of range. Was: %d. Should be"
  1026.                         "[0..31]. Assuming %d.\n",im5,im5&0x1f);
  1027.                     im5 = im5 & 0x1f;
  1028.                 }
  1029.                 opcode |= im5 << 21;
  1030.                 s = expr_end;
  1031.                 continue;
  1032.             case 'A':   /* 13 bit immediate at 18 (to support BREAK instr.) */
  1033.                 getAbsoluteExpression(s);
  1034.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE )
  1035.                 opcode |= (the_insn.exp.X_add_number & 0x1fff) << 13;
  1036.                   s = expr_end;
  1037.                   continue;
  1038.             case 'Z':   /* System Control Completer(for LDA, LHA, etc.) */
  1039.                   if ( *s == ',' && ( *(s+1) == 'm' || *(s+1) == 'M' ) ) {
  1040.                     m = 1;
  1041.                     s += 2;
  1042.                   }
  1043.                   else
  1044.                     m = 0;
  1045.   
  1046.                   opcode |= m << 5;
  1047.                   while ( *s == ' ' || *s == '\t' ) /* skip to next operand */
  1048.                     s++;
  1049.   
  1050.                   continue;
  1051.             case 'D':   /* 26 bit immediate at 31 (to support DIAG instr.) */
  1052.                           /* the action (and interpretation of this operand is
  1053.                              implementation dependent) */
  1054.                   getExpression(s);
  1055.                   if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  1056.                     opcode |= ( (evaluateAbsolute(the_insn.exp,0) & 0x1ffffff) << 1 );
  1057.                   }
  1058.                   else
  1059.                     as_bad("Illegal DIAG operand");
  1060.                       s = expr_end;
  1061.                   continue;
  1062.             case 'f':   /* 3 bit Special Function Unit (SFU) identifier at 25 */
  1063.                   sfu = pa_parse_number(&s);
  1064.                   if ( (sfu > 7) || (sfu < 0) )
  1065.                     as_bad("Illegal SFU identifier: %02x", sfu);
  1066.                   opcode |= (sfu & 7) << 6;
  1067.                   continue;
  1068.             case 'O':   /* 20 bit SFU op. split between 15 bits at 20 and 5 bits at 31 */
  1069.                   getExpression(s);
  1070.                   s = expr_end;
  1071.                   continue;
  1072.             case 'o':   /* 15 bit Special Function Unit operation at 20 */
  1073.                   getExpression(s);
  1074.                   s = expr_end;
  1075.                   continue;
  1076.             case '2':   /* 22 bit SFU op. split between 17 bits at 20
  1077.                                and 5 bits at 31 */
  1078.                   getExpression(s);
  1079.                   s = expr_end;
  1080.                   continue;
  1081.             case '1':   /* 15 bit SFU op. split between 10 bits at 20
  1082.                                and 5 bits at 31 */
  1083.                   getExpression(s);
  1084.                   s = expr_end;
  1085.                   continue;
  1086.             case '0':   /* 10 bit SFU op. split between 5 bits at 20
  1087.                                and 5 bits at 31 */
  1088.                   getExpression(s);
  1089.                   s = expr_end;
  1090.                   continue;
  1091.             case 'u':   /* 3 bit coprocessor unit identifier at 25 */
  1092.                   getExpression(s);
  1093.                   s = expr_end;
  1094.                   continue;
  1095.             case 'F':   /* Source FP Operand Format Completer (2 bits at 20) */
  1096.                   f = pa_parse_fp_format(&s);
  1097.                   opcode |= (int)f << 11;
  1098.                   the_insn.fpof1 = f;
  1099.                   continue;
  1100.             case 'G':   /* Destination FP Operand Format Completer (2 bits at 18) */
  1101.                   s--;    /* need to pass the previous comma to pa_parse_fp_format */
  1102.                   f = pa_parse_fp_format(&s);
  1103.                   opcode |= (int)f << 13;
  1104.                   the_insn.fpof2 = f;
  1105.                   continue;
  1106.             case 'M':   /* FP Compare Conditions (encoded as 5 bits at 31) */
  1107.                   cond = pa_parse_fp_cmp_cond(&s);
  1108.                   opcode |= cond;
  1109.                   continue;
  1110.  
  1111.             case 'v':   /* a 't' type extended to handle L/R register halves. */
  1112.                   {
  1113.                     struct pa_89_fp_reg_struct result;
  1114.  
  1115.                     pa_89_parse_number(&s,&result);
  1116.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1117.                           opcode |= (result.number_part & 0x1f);
  1118.  
  1119.                         /* 0x30 opcodes are FP arithmetic operation opcodes */
  1120.                         /* load/store FP opcodes do not get converted to 0x38 */
  1121.                         /* opcodes like the 0x30 opcodes do */
  1122.                         if ( need_89_opcode(&the_insn,&result) ) {
  1123.                             if ( (opcode & 0xfc000000) == 0x30000000 ) {
  1124.                                 opcode |= (result.L_R_select & 1) << 6;
  1125.                                 opcode |= 1 << 27;
  1126.                             }
  1127.                             else {
  1128.                                 opcode |= (result.L_R_select & 1) << 6;
  1129.                             }
  1130.                         }
  1131.                         continue;
  1132.                     }
  1133.                 }
  1134.                 break;
  1135.             case 'E':   /* a 'b' type extended to handle L/R register halves. */
  1136.                 {
  1137.                     struct pa_89_fp_reg_struct result;
  1138.  
  1139.                     pa_89_parse_number(&s,&result);
  1140.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1141.                         opcode |= (result.number_part & 0x1f) << 21;
  1142.                         if ( need_89_opcode(&the_insn,&result) ) {
  1143.                             opcode |= (result.L_R_select & 1) << 7;
  1144.                             opcode |= 1 << 27;
  1145.                         }
  1146.                         continue;
  1147.                     }
  1148.                 }
  1149.                 break;
  1150.  
  1151.             case 'X':   /* an 'x' type extended to handle L/R register halves. */
  1152.                 {
  1153.                     struct pa_89_fp_reg_struct result;
  1154.  
  1155.  
  1156.                     pa_89_parse_number(&s,&result);
  1157.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1158.                         opcode |= (result.number_part & 0x1f) << 16;
  1159.                         if ( need_89_opcode(&the_insn,&result) ) {
  1160.                             opcode |= (result.L_R_select & 1) << 12;
  1161.                             opcode |= 1 << 27;
  1162.                         }
  1163.                         continue;
  1164.                     }
  1165.                 }
  1166.                 break;
  1167.  
  1168.             case '4':   /* 5 bit register field at 10
  1169.                         (used in 'fmpyadd' and 'fmpysub') */
  1170.                 {
  1171.                     struct pa_89_fp_reg_struct result;
  1172.                     int status;
  1173.  
  1174.                     status = pa_89_parse_number(&s,&result);
  1175.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1176.                         if ( the_insn.fpof1 == SGL ) {
  1177.                             result.number_part &= 0xF;
  1178.                             result.number_part |= (result.L_R_select & 1) << 4;
  1179.                         }
  1180.                         opcode |= result.number_part << 21;
  1181.                         continue;
  1182.                     }
  1183.                 }
  1184.                 break;
  1185.  
  1186.             case '6':   /* 5 bit register field at 15
  1187.                         (used in 'fmpyadd' and 'fmpysub') */
  1188.                 {
  1189.                     struct pa_89_fp_reg_struct result;
  1190.                     int status;
  1191.  
  1192.                     status = pa_89_parse_number(&s,&result);
  1193.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1194.                         if ( the_insn.fpof1 == SGL ) {
  1195.                             result.number_part &= 0xF;
  1196.                             result.number_part |= (result.L_R_select & 1) << 4;
  1197.                         }
  1198.                         opcode |= result.number_part << 16;
  1199.                         continue;
  1200.                     }
  1201.                 }
  1202.                 break;
  1203.  
  1204.             case '7':   /* 5 bit register field at 31
  1205.                         (used in 'fmpyadd' and 'fmpysub') */
  1206.                 {
  1207.                     struct pa_89_fp_reg_struct result;
  1208.                     int status;
  1209.  
  1210.                     status = pa_89_parse_number(&s,&result);
  1211.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1212.                         if ( the_insn.fpof1 == SGL ) {
  1213.                             result.number_part &= 0xF;
  1214.                             result.number_part |= (result.L_R_select & 1) << 4;
  1215.                         }
  1216.                         opcode |= result.number_part;
  1217.                         continue;
  1218.                     }
  1219.                 }
  1220.                 break;
  1221.  
  1222.             case '8':   /* 5 bit register field at 20
  1223.                         (used in 'fmpyadd' and 'fmpysub') */
  1224.                 {
  1225.                     struct pa_89_fp_reg_struct result;
  1226.                     int status;
  1227.  
  1228.                     status = pa_89_parse_number(&s,&result);
  1229.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1230.                         if ( the_insn.fpof1 == SGL ) {
  1231.                             result.number_part &= 0xF;
  1232.                             result.number_part |= (result.L_R_select & 1) << 4;
  1233.                         }
  1234.                         opcode |= result.number_part << 11;
  1235.                         continue;
  1236.                     }
  1237.                 }
  1238.                 break;
  1239.  
  1240.             case '9':   /* 5 bit register field at 25
  1241.                         (used in 'fmpyadd' and 'fmpysub') */
  1242.                 {
  1243.                     struct pa_89_fp_reg_struct result;
  1244.                     int status;
  1245.  
  1246.                     status = pa_89_parse_number(&s,&result);
  1247.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1248.                         if ( the_insn.fpof1 == SGL ) {
  1249.                             result.number_part &= 0xF;
  1250.                             result.number_part |= (result.L_R_select & 1) << 4;
  1251.                         }
  1252.                         opcode |= result.number_part << 6;
  1253.                         continue;
  1254.                     }
  1255.                 }
  1256.                 break;
  1257.  
  1258.             case 'H':  /* Floating Point Operand Format at 26 for       */
  1259.                         /* 'fmpyadd' and 'fmpysub' (very similar to 'F') */
  1260.                         /* bits are switched from other FP Operand       */
  1261.                         /* formats. 1=SGL, 1=<none>, 0=DBL               */
  1262.                 f = pa_parse_fp_format(&s);
  1263.                 switch (f) {
  1264.                 case SGL:
  1265.                     opcode |= 0x20;
  1266.                 case DBL:
  1267.                     the_insn.fpof1 = f;
  1268.                     continue;
  1269.  
  1270.                 case QUAD:
  1271.                 case ILLEGAL_FMT:
  1272.                 default:
  1273.                     as_bad("Illegal Floating Point Operand Format for"
  1274.                         "this instruction: '%s'",s);
  1275.                 }
  1276.                 break;
  1277.  
  1278.             case 'y' :  /* nullify at 26 */
  1279.                 nullif = pa_parse_nullif(&s);
  1280.                 opcode |= nullif << 5;
  1281.                 continue;
  1282.                         
  1283. /* bug #41317 .... umeshv@NeXT.com Mon May  2 17:53:29 PDT 1994
  1284.  
  1285.    These are for 'cache control hints'
  1286.     
  1287.     l    Store Instruction Cache Control Hint  (Table 5-8) with
  1288.         Short displacement load and store completers (Table 5-11) 
  1289.          
  1290.     L    Load and Clear Word Cache Control Hint (Table 5-9) with
  1291.         Indexed load completers (Table 5-10)
  1292.  
  1293.     3    Store Instruction Cache Control Hint  (Table 5-8) with
  1294.         Indexed load completers (Table 5-10)
  1295.  
  1296.     a    Load and Clear Word Cache Control Hint (Table 5-9) with
  1297.         Short displacement load and store completers (Table 5-11)
  1298.  
  1299.     These parse ",cc" and encode "cc" in 2 bits at 20,
  1300.     where "cc" encoding is as given in Tables 5-8, 5-9.
  1301.     Refer to 'PA-RISC 1.1 Architecture and Instruction Set Reference
  1302.     Manual, Second Edition' for the tables.
  1303. */
  1304.  
  1305.             case 'l' :  /* Store Instruction Cache Control Hint */
  1306.                         /* Short displacement load and store completers */
  1307.                 opcode |= parse_completer_with_cache_control_hint(&s, 0, 'C');
  1308.                 continue;
  1309.  
  1310.             case 'L' :  /* Load and Clear Word Cache Control Hint */
  1311.                         /* Indexed load completers  */
  1312.                 opcode |= parse_completer_with_cache_control_hint(&s, 1, 'c');
  1313.                 continue;
  1314.  
  1315.             case '3' :  /* Store Instruction Cache Control Hint */
  1316.                         /* Indexed load completers */
  1317.                 opcode |= parse_completer_with_cache_control_hint(&s, 0, 'c');
  1318.                 continue;
  1319.  
  1320.             case 'a' :  /* Load and Clear Word Cache Control Hint */
  1321.                         /* Short displacement load and store completers */
  1322.                 opcode |= parse_completer_with_cache_control_hint(&s, 1, 'C');
  1323.                 continue;
  1324.  
  1325.             default:
  1326.                 abort();
  1327.             }
  1328.             break;
  1329.         }
  1330.  
  1331.         if (match == FALSE)
  1332.         {
  1333.         /* Args don't match.  */
  1334.             if (&insn[1] - pa_opcodes < NUMOPCODES
  1335.                 && !strcmp(insn->name, insn[1].name))
  1336.             {
  1337.                 ++insn;
  1338.                 s = argsStart;
  1339.                 continue;
  1340.             }
  1341.             else
  1342.             {
  1343.                 as_bad("Illegal operands");
  1344.                 return;
  1345.             }
  1346.         }
  1347.         break;
  1348.     }
  1349.  
  1350.     the_insn.opcode = opcode;
  1351.     return;
  1352. }    /* end pa_ip() */
  1353.  
  1354. /*
  1355.     This is identical to the md_atof in m68k.c.  I think this is right,
  1356.     but I'm not sure.
  1357.  
  1358.    Turn a string in input_line_pointer into a floating point constant of type
  1359.    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
  1360.    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
  1361.  */
  1362.  
  1363. /* Equal to MAX_PRECISION in atof-ieee.c */
  1364. #define MAX_LITTLENUMS 6
  1365.  
  1366. char *
  1367. md_atof(
  1368. int type,
  1369. char *litP,
  1370. int *sizeP)
  1371. {
  1372.     int    prec;
  1373.     LITTLENUM_TYPE words[MAX_LITTLENUMS];
  1374.     LITTLENUM_TYPE *wordP;
  1375.     char    *t;
  1376.     char    *atof_ieee();
  1377.  
  1378.     switch(type) {
  1379.  
  1380.     case 'f':
  1381.     case 'F':
  1382.     case 's':
  1383.     case 'S':
  1384.     prec = 2;
  1385.     break;
  1386.  
  1387.     case 'd':
  1388.     case 'D':
  1389.     case 'r':
  1390.     case 'R':
  1391.     prec = 4;
  1392.     break;
  1393.  
  1394.     case 'x':
  1395.     case 'X':
  1396.     prec = 6;
  1397.     break;
  1398.  
  1399.     case 'p':
  1400.     case 'P':
  1401.     prec = 6;
  1402.     break;
  1403.  
  1404.     default:
  1405.     *sizeP=0;
  1406.     return "Bad call to MD_ATOF()";
  1407.     }
  1408.     t=atof_ieee(input_line_pointer,type,words);
  1409.     if(t)
  1410.     input_line_pointer=t;
  1411.     *sizeP=prec * sizeof(LITTLENUM_TYPE);
  1412.     for(wordP=words;prec--;) {
  1413.     md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
  1414.     litP+=sizeof(LITTLENUM_TYPE);
  1415.     }
  1416.     return "";    /* Someone should teach Dean about null pointers */
  1417. }
  1418.  
  1419. /*
  1420.  * Write out big-endian.
  1421.  */
  1422. void
  1423. md_number_to_chars(
  1424. char *buf,
  1425. long val,
  1426. int n)
  1427. {
  1428.  
  1429.     switch(n) {
  1430.  
  1431.     case 4:
  1432.     *buf++ = val >> 24;
  1433.     *buf++ = val >> 16;
  1434.     case 2:
  1435.     *buf++ = val >> 8;
  1436.     case 1:
  1437.     *buf = val;
  1438.     break;
  1439.  
  1440.     default:
  1441.     abort();
  1442.     }
  1443.     return;
  1444. }
  1445.  
  1446. void
  1447. md_number_to_imm(
  1448. unsigned char *buf,
  1449. long val,
  1450. int n,
  1451. fixS *fixP,
  1452. int nsect)
  1453. {
  1454.     unsigned long w1,w2,w;
  1455.     unsigned new_val = 0;
  1456.     unsigned long left21, right14;
  1457.     
  1458.     if(fixP->fx_r_type == NO_RELOC ||
  1459.        fixP->fx_r_type == HPPA_RELOC_VANILLA){
  1460.         switch(n){
  1461.         case 4:
  1462.         *buf++ = val >> 24;
  1463.         *buf++ = val >> 16;
  1464.         case 2:
  1465.         *buf++ = val >> 8;
  1466.         case 1:
  1467.         *buf = val;
  1468.         break;
  1469.  
  1470.         default:
  1471.         abort();
  1472.         }
  1473.         return;
  1474.     }
  1475.  
  1476.  
  1477.     calc_hppa_HILO(val - fixP->fx_offset, fixP->fx_offset,
  1478.                &left21, &right14);
  1479.  
  1480.     switch (fixP->fx_r_type) {
  1481.     default:
  1482.         break;
  1483. /*     case 'j': */
  1484.     case HPPA_RELOC_LO14 :
  1485.          w = low_sign_unext(right14, 14); 
  1486.         goto fixit;
  1487.  
  1488. /*     case 'k': */
  1489.     case HPPA_RELOC_HI21 :
  1490.         w = dis_assemble_21((left21>>11));
  1491. fixit:
  1492.       /* There is no guarantee that buf is word-aligned,    */
  1493.       /* so the adjustment must be done the hard way.        */
  1494.  
  1495.         new_val  = (*buf & 0xff) << 24;
  1496.         new_val |= (*(buf+1) & 0xff) << 16;
  1497.         new_val |= (*(buf+2) & 0xff) << 8;
  1498.         new_val |= (*(buf+3) & 0xff);
  1499.         new_val |= w;    /* Now, make the adjustment */
  1500.         md_number_to_chars(buf,new_val,4);
  1501.         break;
  1502.  
  1503. /*     case 'W': */
  1504.     case HPPA_RELOC_BL17 :
  1505.         if ( !fixP->fx_addsy ) {
  1506.             val -= 4;    /* PA adjustment: a 0 disp is actually 4 bytes */
  1507.                         /* further because of the delay slot */
  1508.             val >>= 2;
  1509.             dis_assemble_17(val,&w1,&w2,&w);
  1510.         /* There is no guarantee that buf is word-aligned,    */
  1511.         /* so the adjustment must be done the hard way.        */
  1512.  
  1513.         new_val  = (*buf & 0xff) << 24;
  1514.         new_val |= (*(buf+1) & 0xff) << 16;
  1515.         new_val |= (*(buf+2) & 0xff) << 8;
  1516.         new_val |= (*(buf+3) & 0xff);
  1517.         new_val |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
  1518.                       /* Now, do the adjustment */
  1519.         md_number_to_chars(buf,new_val,4);
  1520.       }
  1521.       else {
  1522.         unsigned long result;
  1523.           val -= 4;    /* PA adjustment: a 0 disp is actually 4 bytes */
  1524.                         /* further because of the delay slot */
  1525.         val >>= 2;
  1526.  
  1527.         result = sign_unext( val,17);
  1528.         dis_assemble_17(result,&w1,&w2,&w);
  1529.         /* There is no guarantee that buf is word-aligned,    */
  1530.         /* so the adjustment must be done the hard way.        */
  1531.  
  1532.         new_val  = (*buf & 0xff) << 24;
  1533.         new_val |= (*(buf+1) & 0xff) << 16;
  1534.         new_val |= (*(buf+2) & 0xff) << 8;
  1535.         new_val |= (*(buf+3) & 0xff);
  1536.         new_val |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
  1537.                       /* Now, do the adjustment */
  1538.         md_number_to_chars(buf,new_val,4);
  1539.  
  1540.         }
  1541.         break;
  1542. /*     case 'z': */
  1543.     case HPPA_RELOC_BR17 :
  1544.     {
  1545.         unsigned long result;
  1546.         right14 >>= 2;
  1547.         result = sign_unext(right14,17);
  1548.         dis_assemble_17(result,&w1,&w2,&w);
  1549.     /* There is no guarantee that buf is word-aligned,    */
  1550.     /* so the adjustment must be done the hard way.        */
  1551.  
  1552.         new_val  = (*buf & 0xff) << 24;
  1553.         new_val |= (*(buf+1) & 0xff) << 16;
  1554.         new_val |= (*(buf+2) & 0xff) << 8;
  1555.         new_val |= (*(buf+3) & 0xff);
  1556.         new_val |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
  1557.                       /* Now, do the adjustment */
  1558.         md_number_to_chars(buf,new_val,4);
  1559.      }
  1560.             break;
  1561. /*     case '@': */
  1562.     case HPPA_RELOC_JBSR :
  1563. /*
  1564.  * In case of the jbsr relocation no bytes are to be written to the 
  1565.  * output.
  1566.  * 
  1567.  * SO DO NOTHING!
  1568.  */
  1569.       break;
  1570.       
  1571. /*      case 'w': */
  1572. /* To take care of 12 bit label */
  1573.       case HPPA_RELOC_12BRANCH :
  1574.         if ( !fixP->fx_addsy ) {
  1575.             val -= 4;    /* PA adjustment: a 0 disp is actually 4 bytes */
  1576.                         /* further because of the delay slot */
  1577.             val >>= 2;
  1578.             dis_assemble_12(val,&w1,&w);
  1579.             /* There is no guarantee that buf is word-aligned,    */
  1580.             /* so the adjustment must be done the hard way.        */
  1581.  
  1582.             new_val  = (*buf & 0xff) << 24;
  1583.             new_val |= (*(buf+1) & 0xff) << 16;
  1584.             new_val |= (*(buf+2) & 0xff) << 8;
  1585.             new_val |= (*(buf+3) & 0xff);
  1586.             new_val |= ( ( w1 << 2 ) | w );    /* Now, do the adjustment */
  1587.             md_number_to_chars(buf,new_val,4);
  1588.         }
  1589.         else {
  1590.             as_bad("Undefined symbol %s", fixP->fx_addsy->sy_name);
  1591.         }
  1592.         
  1593.          break;
  1594.     }
  1595. }
  1596.  
  1597. void
  1598. md_convert_frag(
  1599. fragS *fragP)
  1600. {
  1601.   unsigned int address;
  1602.  
  1603.   if ( fragP -> fr_type == rs_machine_dependent ) {
  1604.     switch ( (int) fragP -> fr_subtype ) {
  1605.     case 0:
  1606.       fragP -> fr_type = rs_fill;
  1607.       know( fragP -> fr_var == 1 );
  1608.       know( fragP -> fr_next );
  1609.       address = fragP -> fr_address + fragP -> fr_fix;
  1610.       if ( address % fragP -> fr_offset ) {
  1611.     fragP -> fr_offset =
  1612.       fragP -> fr_next -> fr_address
  1613.         -   fragP -> fr_address
  1614.           - fragP -> fr_fix;
  1615.       }
  1616.       else
  1617.     fragP -> fr_offset = 0;
  1618.       break;
  1619.     }
  1620.   }
  1621. }
  1622.  
  1623. int
  1624. md_estimate_size_before_relax(
  1625. fragS *fragP,
  1626. int nsect)
  1627. {
  1628.   int size;
  1629.  
  1630.   size = 0;
  1631.  
  1632.   while ( (fragP->fr_fix + size) % fragP->fr_offset )
  1633.     size++;
  1634.  
  1635.   return size;
  1636. }
  1637.  
  1638. int
  1639. md_parse_option(
  1640. char **argP,
  1641. int *cntP,
  1642. char ***vecP)
  1643. {
  1644.     return 1;
  1645. }
  1646.  
  1647. /*
  1648. int is_end_of_statement()
  1649. {
  1650.   return (   (*input_line_pointer == '\n')
  1651.       || (*input_line_pointer == ';')
  1652.       || (*input_line_pointer == '!') );
  1653. }
  1654. */
  1655.  
  1656. static
  1657. int
  1658. parse_L_or_R(
  1659. char *str)
  1660. {
  1661. /* not much work done as yet! */
  1662.     switch (*str) {
  1663.     case '%':
  1664.     case '(':
  1665.         return 0;    /* ie. not found */
  1666.         break;
  1667.     case 'L':
  1668.     case 'l':
  1669.         if (*(str+1) == '\'' || *(str+1) == '`') /* check next character */
  1670.             return 1; /* found */
  1671.         else
  1672.             return 0; /* not found */
  1673.         break;
  1674.     case 'R':
  1675.     case 'r':
  1676.         if (*(str+1) == '\'' || *(str+1) == '`') /* check next character */
  1677.             return 2; /* found */
  1678.         else
  1679.             return 0; /* not found */
  1680.         break;
  1681.     default: /* default is not found ... at least for the time being */
  1682.         return 0;
  1683.         break;
  1684.     }
  1685. }    /* end parse_L_or_R() */
  1686.  
  1687. static
  1688. unsigned long
  1689. parse_cache_control_hint(
  1690. char    **s,       /* Note : the function changes '*s' */
  1691. int     option)    /* option = 0 for store instruction */
  1692.                    /* option = 1 for load and clear instruction */
  1693. {
  1694.     unsigned long cc = NO_CACHE_CONTROL_HINT;
  1695.                 
  1696.     if (**s == ',') {
  1697.         (*s)++;
  1698.         switch (option) {
  1699.         case 0 : /* Store Instruction Cache Control Hint */ 
  1700.             if ( strncasecmp(*s,"bc",2) == 0 ) {
  1701.                 /* BLOCK_COPY */
  1702.                 (*s) += 2;
  1703.                 cc = BC_OR_CO_CACHE_CONTROL_HINT;
  1704.                 /* eat up extra blanks and tabs */
  1705.                 while ( **s == ' ' || **s == '\t' )
  1706.                     (*s)++;
  1707.             } else
  1708.                 as_fatal("Illegal Cache Control Hint: '%s'"
  1709.                     " - expected 'bc'",*s);
  1710.             break;
  1711.             
  1712.         case 1 : /* Load and Clear Word Cache Control Hint */
  1713.             if ( strncasecmp(*s,"co",2) == 0 ) {
  1714.                 /* COHERENT_OPERATION */
  1715.                 (*s) +=2;
  1716.                 cc = BC_OR_CO_CACHE_CONTROL_HINT;
  1717.                 /* eat up extra blanks and tabs */
  1718.                 while ( **s == ' ' || **s == '\t' )
  1719.                     (*s)++;
  1720.             } else
  1721.                 as_fatal("Illegal Cache Control Hint: '%s'"
  1722.                     " - expected 'co'",*s);
  1723.             break;
  1724.             
  1725.         default :
  1726.             as_fatal("Invalid option (%d) for parsing cache control hints",
  1727.                 option);
  1728.             break;
  1729.         }
  1730.     }
  1731.         /* else NO_HINT */
  1732.                 
  1733.     /*
  1734.     * the completers have already eaten up extra blanks
  1735.     * and tabs. So there is no need to do that again here.
  1736.     */
  1737.                  
  1738.     return cc;
  1739.  
  1740. }    /* end parse_cache_control_hint() */
  1741.  
  1742. static
  1743. unsigned long
  1744. parse_completer_with_cache_control_hint(
  1745. char    **s,       /* Note : the function changes '*s' */
  1746. int     option,    /* option = 0 for store instruction */
  1747.                    /* option = 1 for load and clear instruction */
  1748. char    completer) /* 'c' or 'C' */
  1749. {
  1750.     unsigned long i, result = (unsigned long) 0UL;
  1751.     int m, a, u;
  1752.     
  1753.     switch (completer) {
  1754.     case 'c':   /* indexed load completer. */
  1755.         i = m = u = 0;
  1756.         while ( **s == ',' && i < 3 ) {
  1757.             (*s)++;
  1758.             if ( strncasecmp((*s),"sm",2) == 0 ) {
  1759.                 m = u = 1;
  1760.                 (*s)++;
  1761.                 i++;
  1762.             }
  1763.             else if ( strncasecmp((*s),"m",1) == 0 )
  1764.                 m = 1;
  1765.             else if ( strncasecmp((*s),"s",1) == 0 )
  1766.                 u = 1;
  1767.             else if ( strncmp((*s),",",1) == 0 ) /* no completer */
  1768.                 result |= parse_cache_control_hint(s, option);
  1769.             else if ( (strncasecmp((*s),"c",1) == 0) ||
  1770.                       (strncasecmp((*s),"b",1) == 0) ) {/* just 1 completer */
  1771.                 (*s)--;
  1772.                 result |= parse_cache_control_hint(s, option);
  1773.             }
  1774.             else
  1775.                 as_bad("Unrecognized Indexed Load"
  1776.                     "Completer with cache control hints...assuming 0");
  1777.             if (result == (unsigned long)0UL)
  1778.                 (*s)++;
  1779.             i++;
  1780.         }
  1781.         if ( i > 3 )
  1782.             as_bad("Illegal Indexed Load Completer with cache control hints"
  1783.             " Syntax... extras ignored");
  1784.         while ( **s == ' ' || **s == '\t' )
  1785.             (*s)++;
  1786.   
  1787.         result |= m << 5;
  1788.         result |= u << 13;
  1789.         break;
  1790.     case 'C':   /* short load and store completer */
  1791.         i = m = a = 0;
  1792.         while ( **s == ',' && i < 2 ) {
  1793.             (*s)++;
  1794.             if ( strncasecmp((*s),"ma",2) == 0 ) {
  1795.                 a = 0;
  1796.                 m = 1;
  1797.             }
  1798.             else if ( strncasecmp((*s),"mb",2) == 0 ) {
  1799.                 m = a = 1;
  1800.             }
  1801.             else if ( strncmp((*s),",",1) == 0 ) /* no completer */
  1802.                 result |= parse_cache_control_hint(s, option);
  1803.             else if ( (strncasecmp((*s),"c",1) == 0) ||
  1804.                       (strncasecmp((*s),"b",1) == 0) ) {/* just 1 completer */
  1805.                 (*s)--;
  1806.                 result |= parse_cache_control_hint(s, option);
  1807.             }
  1808.             else
  1809.                 as_bad("Unrecognized Indexed Load Completer"
  1810.                 "...assuming 0");
  1811.             i++;
  1812.             (*s) += 2;
  1813.         }
  1814.         while ( **s == ' ' || **s == '\t' )
  1815.             (*s)++;
  1816.         result |= m << 5;
  1817.         result |= a << 13;
  1818.         break;
  1819.         
  1820.         
  1821.     default :
  1822.             as_fatal("Invalid completer (%c) for parsing cache control hints",
  1823.                 completer);
  1824.             break;
  1825.     }
  1826.     return result;
  1827. }    /* end parse_completer_with_cache_control_hint() */
  1828.  
  1829. /* end hppa.c */
  1830.